#include"mythread.h"
#include<stdlib.h>



/*//初始化线程*/
static struct TCB init_task = { 0,NULL,0,0,{0} };

/*//当前线程*/
PtrTCB Mcurrent = &init_task;

/*//线程池32线程*/
PtrTCB TASKS[THR_TASKS] = { &init_task, };

/*//切换线程*/
void Myswitch_to(PtrTCB next)
{
    __asm__ volatile
        (
            "pushl %edi\n"
            "pushl %esi\n"
            "pushl %edx\n"
            "pushl %ecx\n"
            "pushl %ebx\n"
            "pushl %eax\n"
            "pushfl\n"
            );

    __asm__ volatile
        (
            "movl %%esp,8(%0)\n"    /*//保存栈指针  Mcurrent->esp= esp*/
            "movl 8(%%ebp),%0\n"    /*//切换线程    Mcurrent=next*/
            "movl 8(%0),%%esp\n"    /*//切换栈指针  esp=next->esp*/
            :"=a"(Mcurrent)
            :"0"(Mcurrent)
            );

    __asm__ volatile
        (
            "popfl\n"
            "popl %eax\n"
            "popl %ebx\n"
            "popl %ecx\n"
            "popl %edx\n"
            "popl %esi\n"
            "popl %edi\n"
            );
}


/*//创建线程*/
int thread_create(int* tid, void (*start_routine)())
{
    int Mid = -1;
    /*//找到可以放线程的位子*/

    while (++Mid < THR_TASKS && TASKS[Mid]);

    /*//无位置*/
    if (Mid >= THR_TASKS)
    {

#ifdef debug
        printf("thread full\n");
#endif
        return -1;
    }

    PtrTCB tmp = (PtrTCB)malloc(sizeof(struct TCB));

    tmp->id = Mid;
    tmp->thread_func = start_routine;/*//连接功能函数*/
    int* stack = tmp->stack;

   /* //初始化栈指针*/
    tmp->esp = (int)(stack + STACK_SIZE - 11);
   /* //标记当前状态为运行*/
    tmp->status = THREAD_STATUS_RUNNING;

    stack[STACK_SIZE - 11] = 7;         /*// eflags寄存器*/
    stack[STACK_SIZE - 10] = 6;         /*// eax寄存器*/
    stack[STACK_SIZE - 9] = 5;          /*// ebx寄存器*/
    stack[STACK_SIZE - 8] = 4;          /*// ecx寄存器*/
    stack[STACK_SIZE - 7] = 3;          /*// edx寄存器*/
    stack[STACK_SIZE - 6] = 2;          /*// esi寄存器*/
    stack[STACK_SIZE - 5] = 1;          /*// edi寄存器*/
    stack[STACK_SIZE - 4] = 0;          /*// old ebp寄存器*/
    stack[STACK_SIZE - 3] = (int)start; /*// ret to start函数*/
    stack[STACK_SIZE - 2] = 100;        /*// ret to unknown*/
    stack[STACK_SIZE - 1] = (int)tmp;   /*// The args of starth函数的元素*/

  /* //保存tcb*/
    TASKS[Mid] = tmp;
    /*//返回分配到的线程地址*/
    *tid = Mid;
    return 0;
}

/*//寻找下一个可用线程*/
PtrTCB Myfindnext()
{
    PtrTCB next = NULL;
    int i = 0;
    for (i = 1;i < 32;i++)
    {
        if (i == Mcurrent->id)continue;
        if (TASKS[i] && TASKS[i]->status == THREAD_STATUS_RUNNING)
        {
            next = TASKS[i];
            break;
        }
    }

    if (next)return next;
    else if (Mcurrent->status == THREAD_STATUS_RUNNING)return Mcurrent;
    else return TASKS[0];
}





/*//切换调度*/
int MyYield()
{
    PtrTCB Next = Myfindnext();
    if (Next)
    {
        Myswitch_to(Next);
    }
   /* //所有都被推出了调度结束*/
}





/*//启动函数*/
void start(PtrTCB TSK)
{
    /*//运行函数*/
    TSK->thread_func();
    /*/函数结束了*/
#ifdef debug
    printf("exit threadID:%d\n", TSK->id);
#endif



    TSK->status = THREAD_STATUS_EXIT;

    MyYield();
}

void Mythreadfree(int pid)
{
    if (TASKS[pid]->status == THREAD_STATUS_RUNNING)
        MyYield();
    else
    {
        free(TASKS[pid]);
#ifdef debug
        printf("free memory threadID:%d\n", pid);
#endif
        TASKS[pid] = NULL;
    }
}
